package com.freewater.cargotracker.domain.model.cargo;

import com.freewater.cargotracker.domain.common.Entity;
import com.freewater.cargotracker.domain.model.location.Location;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.EqualsBuilder;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 航段
 */
public class Leg implements Serializable, Entity {

    private static final long serialVersionUID = 1L;

    private Long id;
    private Long voyageId;
    private Location loadLocation;
    private Location unloadLocation;
    private LocalDateTime loadTime;
    private LocalDateTime unloadTime;

    public Leg(Long voyageId,
               Location loadLocation,
               Location unloadLocation,
               LocalDateTime loadTime,
               LocalDateTime unloadTime) {
        Validate.notNull(voyageId, "Voyage id is required");
        Validate.notNull(loadLocation, "Load location is required");
        Validate.notNull(unloadLocation, "Unload location is required");
        Validate.notNull(loadTime, "Load time is required");
        Validate.notNull(unloadTime, "Unload time is required");

        this.voyageId = voyageId;
        this.loadLocation = loadLocation;
        this.unloadLocation = unloadLocation;
        this.loadTime = loadTime;
        this.unloadTime = unloadTime;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        Validate.notNull(id, "id is required");
        this.id = id;
    }

    public Long getVoyageId() {
        return voyageId;
    }

    public Location getLoadLocation() {
        return loadLocation;
    }

    public Location getUnloadLocation() {
        return unloadLocation;
    }

    public LocalDateTime getLoadTime() {
        return loadTime;
    }

    public void setLoadTime(LocalDateTime loadTime) {
        this.loadTime = loadTime;
    }

    public LocalDateTime getUnloadTime() {
        return unloadTime;
    }

    public void setUnloadTime(LocalDateTime unloadTime) {
        this.unloadTime = unloadTime;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Leg)) return false;
        Leg leg = (Leg) o;
        return sameValueAs(leg);
    }

    private boolean sameValueAs(Leg other) {
        return other != null
                && new EqualsBuilder()
                .append(this.voyageId, other.voyageId)
                .append(this.loadLocation, other.loadLocation)
                .append(this.unloadLocation, other.unloadLocation)
                .append(this.loadTime, other.loadTime)
                .append(this.unloadTime, other.unloadTime)
                .isEquals();
    }

    @Override
    public int hashCode() {
        return Objects.hash(voyageId, loadLocation, unloadLocation, loadTime, unloadTime);
    }

    @Override
    public String toString() {
        return "Leg{" +
                "id=" + id +
                ", voyageId=" + voyageId +
                ", loadLocation=" + loadLocation +
                ", unloadLocation=" + unloadLocation +
                ", loadTime=" + loadTime +
                ", unloadTime=" + unloadTime +
                '}';
    }
}
